/**
 * Project Name:fire-industry-DM-center
 * File Name:MyElasticsearchServiceImpl.java
 * Package Name:com.firestone.service.elasticsearch.impl
 * Date:2018年4月17日上午11:29:58
 *
*/

package com.firestone.service.elasticsearch.impl;

import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.nested.Nested;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.ResultsExtractor;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Service;

import com.firestone.bean.entity.elasticsearch.im.DmImPatent;
import com.firestone.service.elasticsearch.IMyElasticsearchService;

/**
 * @Description: TODO(自定义ES搜索业务)
 * @author CAIYJ
 * @date 2018年4月17日 上午11:29:58
 */
@Service
public class MyElasticsearchServiceImpl implements IMyElasticsearchService {

    @Autowired
    private ElasticsearchOperations elasticsearchOperations;

    @Override
    public <T> Map<String, Long> nestedAggs(QueryBuilder queryBuilder,
            String nestedName, String nestedPath, String termName,
            String termField, Class<T> clazz) throws Exception {
        if (null == queryBuilder || StringUtils.isBlank(nestedName)
                || StringUtils.isBlank(nestedPath)
                || StringUtils.isBlank(termName)
                || StringUtils.isBlank(termField) || null == clazz) {
            return null;
        }
        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(queryBuilder)
                .addAggregation(AggregationBuilders
                        .nested(nestedName, nestedPath)
                        .subAggregation(AggregationBuilders.terms(termName)
                                .field(termField).size(Integer.MAX_VALUE)))
                .withIndices(elasticsearchOperations
                        .getPersistentEntityFor(clazz).getIndexName())
                .withTypes(elasticsearchOperations.getPersistentEntityFor(clazz)
                        .getIndexType())
                .build();
        searchQuery.setPageable(PageRequest.of(0, 1));// 设置最小命中数，减小查询传输开销
        Aggregations aggregations = elasticsearchOperations.query(searchQuery,
                new ResultsExtractor<Aggregations>() {
                    @Override
                    public Aggregations extract(SearchResponse response) {
                        return response.getAggregations();
                    }
                });
        if (aggregations != null) {
            Map<String, Long> map = new LinkedHashMap<>();
            Nested nested = aggregations.get(nestedName);
            Terms terms = nested.getAggregations().get(termName);
            for (Terms.Bucket bucket : terms.getBuckets()) {
                map.put(bucket.getKeyAsString(), bucket.getDocCount());
            }
            return map;
        }
        return null;
    }

    @Override
    public <T> Map<String, Long> termAggs(QueryBuilder queryBuilder,
            String termName, String termField, Class<T> clazz)
                    throws Exception {
        if (null == queryBuilder || StringUtils.isBlank(termName)
                || StringUtils.isBlank(termField) || null == clazz) {
            return null;
        }
        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(queryBuilder)
                .addAggregation(AggregationBuilders.terms(termName)
                        .field(termField).size(Integer.MAX_VALUE))
                .withIndices(elasticsearchOperations
                        .getPersistentEntityFor(clazz).getIndexName())
                .withTypes(elasticsearchOperations.getPersistentEntityFor(clazz)
                        .getIndexType())
                .build();
        searchQuery.addTypes(elasticsearchOperations
                .getPersistentEntityFor(DmImPatent.class).getIndexType());
        searchQuery.addIndices(elasticsearchOperations
                .getPersistentEntityFor(DmImPatent.class).getIndexName());
        Aggregations aggregations = elasticsearchOperations.query(searchQuery,
                new ResultsExtractor<Aggregations>() {
                    @Override
                    public Aggregations extract(SearchResponse response) {
                        return response.getAggregations();
                    }
                });
        searchQuery.setPageable(PageRequest.of(0, 1));// 设置最小命中数，减小查询传输开销
        Terms terms = aggregations.get(termName);
        Map<String, Long> map = new LinkedHashMap<>();
        for (Terms.Bucket bucket : terms.getBuckets()) {
            map.put(bucket.getKeyAsString(), bucket.getDocCount());
        }
        return map;
    }

}
